﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LCA.Community.Web.Filters;
using LCA.Community.Web.Models;
using Microsoft.Practices.Unity;
using LCA.Community.DAL.Interfaces;
using LCA.Community.DAL.Model;

namespace LCA.Community.Web.Controllers
{
    /// <summary>
    /// Controller for managing voluteers actions.
    /// </summary>
    public class VolunteerController : BaseController
    {
        /// <summary>
        /// Index for showing volunteer relationship of the user.
        /// </summary>
        /// <param name="id">The user id.</param>
        /// <returns>View showing the volunteer relationships of the user.</returns>
        [SecurityFilter(SecurityRequisites = "Owner,Admin", SolvingActionParameter = "id", ErrorResource = "NoAuthorized")]
        [ErrorFilter(typeof(ArgumentException), "UserNotFound", 0)]
        public ActionResult Index(string id)
        {
            var volunteerViewModel = MvcApplication.Container.Resolve<VolunteerViewModel>(new ParameterOverrides { { "userID", id } });

            var user = UsersRepository.Get(id);
            if (user == null)
                new ArgumentException("User not found");

            ViewData["owner"] = IsOwner(id);
            ViewData["user"] = UsersRepository.Get(id);
            return View(volunteerViewModel);
        }

        /// <summary>
        /// Action for searching volunteers;
        /// </summary>
        /// <returns>View for searching for volunteers.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NoAuthorized")]
        public ActionResult SearchVolunteers()
        {
            var user = UsersRepository.Get(UserID);
            ViewData["user"] = user;
            ViewData["owner"] = true;
            return View();
        }

        /// <summary>
        /// Action for searching volunteers from a city;
        /// </summary>
        /// <returns>Partial view with the result of the search.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NoAuthorized")]
        public ActionResult SearchVolunteersFromCity(string city)
        {
            var user = UsersRepository.Get(UserID);
            ViewData["user"] = user;
            ViewData["owner"] = true;

            var volunteers = UsersRepository.GetVolunteerByCity(city);
            return PartialView("ShowVolunteers", volunteers);
        }

        /// <summary>
        /// Action for requesting help.
        /// </summary>
        /// <param name="volunteerID">The volunteer ID.</param>
        /// <param name="userID">The user ID.</param>
        /// <returns>View for searching a volunteer.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NoAuthorized")]
        public ActionResult AskForHelp(string volunteerID)
        {
            if (MessagesRepository.GetHelpRequest(UserID,volunteerID) == null)
            {
                Message message = CreateAskForHelpMessage(UserID,volunteerID);
                MessagesRepository.Add(message);
            }

            return RedirectToAction("SearchVolunteers", "Volunteer");
        }

        /// <summary>
        /// Action for accepting a help request
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <returns>View showing the mailbox of the user</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NoAuthorized")]
        public ActionResult AcceptHelpRequest(string userID)
        {
            Message message = MessagesRepository.GetHelpRequest(userID,UserID);
            if (message != null)
            {
                HelpRelationshipRepository.Add(new HelpRelationship(UserID, userID));
                MessagesRepository.Delete(message);

                MessagesRepository.Add(CreateAcceptHelpRequestMessage(userID,UserID));
            }

            return RedirectToAction("Index", "Mailbox", new { id = UserID });
        }

        /// <summary>
        /// Action for denying a help request.
        /// </summary>
        /// <param name="volunteerID">The volunteer ID.</param>
        /// <param name="userID">The user ID.</param>
        /// <returns>View showing the mailbox of the user.</returns>
        [SecurityFilter(SecurityRequisites = "Registered", ErrorResource = "NoAuthorized")]
        public ActionResult DenyHelpRequest(string userID)
        {
            Message message = MessagesRepository.GetHelpRequest(userID, UserID);
            if (message != null)
            {
                MessagesRepository.Delete(message);

                MessagesRepository.Add(CreateDenyHelpRequestMessage(userID,UserID));
            }
            return RedirectToAction("Index", "Mailbox", new { id = UserID });
        }

        /// <summary>
        /// Creates an ask for help message.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="volunteerID">The volunteer ID.</param>
        /// <returns>Ask for help message.</returns>
        private Message CreateAskForHelpMessage(string userID, string volunteerID)
        {
            string subject = string.Format("Help Request: Solicitud de ayuda", userID);
            string acceptlink = string.Format("<a href=\"{0}\">aquí</a>", Url.Action("AcceptHelpRequest", "Volunteer", new { userID }));
            string denylink = string.Format("<a href=\"{0}\">aquí</a>", Url.Action("DenyHelpRequest", "Volunteer", new { userID }));
            string body = string.Format("El usuario {0} ha solicitado tu ayuda.<br />Para aceptar tu ayuda pincha {1}<br>Para denegarle tu ayuda pincha {2}", userID, acceptlink, denylink);
            return new Message(userID, subject, body, new List<string> { volunteerID });
        }

        /// <summary>
        /// Creates an accept help request message.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="volunteerID">The volunteer ID.</param>
        /// <returns>Accept help request message.</returns>
        private Message CreateAcceptHelpRequestMessage(string userID, string volunteerID)
        {
            string subject = string.Format("Help Request: El usuario {0} ha aceptado ayudarte", volunteerID);
            string body = "A partir de ahora puedes enviarle mensajes específicamente a él";
            return new Message(volunteerID, subject, body, new List<string> { userID });
        }

        /// <summary>
        /// Creates a deny help request message.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="volunteerID">The volunteer ID.</param>
        /// <returns>Deny help request message.</returns>
        private Message CreateDenyHelpRequestMessage(string userID, string volunteerID)
        {
            string subject = string.Format("Help Request: El usuario {0} no ha aceptado ayudarte", volunteerID);
            string body = "Puedes buscar a otra persona para que te ayude";
            return new Message(volunteerID, subject, body, new List<string> { userID });
        }

        [Dependency]
        public IUsersRepository UsersRepository { get; set; }
        [Dependency]
        public IMessagesRepository MessagesRepository { get; set; }
        [Dependency]
        public IHelpRelationshipsRepository HelpRelationshipRepository { get; set; }
    }
}